package com.yu.hu.navigation

import android.os.Bundle
import androidx.compose.animation.AnimatedContentTransitionScope
import androidx.compose.animation.core.tween
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.LifecycleOwner
import androidx.navigation.NavController
import androidx.navigation.NavDestination
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import com.yu.hu.base.util.Logger

/**
 * huyu create
 * 2025/11/4 8:56
 */

@Composable
fun AppNavHost(
    navController: NavHostController,
    startDestination: Any,
    builder: NavGraphBuilder.() -> Unit
) {
    //添加全局导航跳转监听
    DisposableEffect(navController) {
        val listener = newDestinationChangedListener()
        navController.addOnDestinationChangedListener(listener)
        onDispose {
            navController.removeOnDestinationChangedListener(listener)
        }
    }

    NavHost(
        navController = navController,
        startDestination = startDestination,
        // 页面进入动画
        enterTransition = {
            slideIntoContainer(
                AnimatedContentTransitionScope.SlideDirection.Left,
                animationSpec = tween(300)
            )
        },
        // 页面退出动画
        exitTransition = {
            slideOutOfContainer(
                AnimatedContentTransitionScope.SlideDirection.Left,
                animationSpec = tween(300)
            )
        },
        // 返回时页面进入动画
        popEnterTransition = {
            slideIntoContainer(
                AnimatedContentTransitionScope.SlideDirection.Right,
                animationSpec = tween(300)
            )
        },
        // 返回时页面退出动画
        popExitTransition = {
            slideOutOfContainer(
                AnimatedContentTransitionScope.SlideDirection.Right,
                animationSpec = tween(300)
            )
        },
        builder = builder
    )
}

private fun newDestinationChangedListener() = object : NavController.OnDestinationChangedListener {

    private val observerMap = HashMap<String, DestinationLifecycleObserver>()

    override fun onDestinationChanged(
        controller: NavController,
        destination: NavDestination,
        arguments: Bundle?
    ) {
        val route = destination.route?.split(".")?.last() ?: "unknown"
        val lifecycleObserver = obtainObserver(route)
        controller.currentBackStackEntry?.lifecycle?.addObserver(lifecycleObserver)
    }

    private fun obtainObserver(route: String): LifecycleEventObserver {
        val observer = observerMap[route]?.takeIf { it.isActive } ?: DestinationLifecycleObserver(route)
        observerMap[route] = observer
        return observer
    }
}

private class DestinationLifecycleObserver(private val route: String) : LifecycleEventObserver {

    var isActive: Boolean = true
        private set

    override fun onStateChanged(
        source: LifecycleOwner,
        event: Lifecycle.Event
    ) {
        if (event == Lifecycle.Event.ON_DESTROY) {
            source.lifecycle.removeObserver(this)
            isActive = false
        }
        Logger.i("NavHost", "$route onStateChanged $event")
    }

}